package java学习.第10章_多线程的入门;

import java.security.SecureRandom;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ClassName: E_线程安全问题
 * Package: java学习.第10章_多线程的入门
 * Description:
 *
 * @Author 张蛟龙
 * @Create 2023/3/18 19:49
 * @Version 1.0
 */
public class E_线程安全问题 {
    /**
     * 为了保证线程安全，synchronized(同步监视器){
     *     需要同步的代码
     * }
     * 好处：解决了线程安全问题
     * 坏处：浪费cpu资源
     *
     *
     *
     */
    public static void main(String[] args) {
        E e = new E();

        int k = 10;
        for (int i = 0; i < k; i++) {
//            new Thread(e, "" + i).start();
            new Thread(e).start();
        }

//        System.out.println(e.ii);
    }
}

class E implements Runnable {
    static int ii = 0;
    static SecureRandom  s = new SecureRandom();

    int k = 100;

//    @Override //有同步监视器
    public void run1() {
        while (k > 0) {
            try { TimeUnit.MILLISECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}
            synchronized (E.class){//加锁，线程安全

                show();
            }
        }
    }

    public void run() {
        while (k > 0) {
            try { TimeUnit.MILLISECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}
            synchronized (E.class){//加锁，线程安全

                show1();
            }
        }
    }
    //非静态方法  默认 this  静态的，默认 本类.class
    private synchronized void show1() {
        if(k>0)
            System.out.println(Thread.currentThread().getName() +
                    "卖出第" + --k + "张票");
    }
    Lock l = new ReentrantLock();
//    @Override
    public void run2() {

        while (k > 0) {
            try { TimeUnit.MILLISECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}
            l.lock();
            show();
            l.unlock();
        }
    }



    private void show() {
        if(k>0)
            System.out.println(Thread.currentThread().getName() +
                    "卖出第" + --k + "张票");
    }
}